package findMedianSortedArrays;

public class Solution2 {
    public double findMedianSortedArrays(int[] nums1, int[] nums2){
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    public int getKthElement(int[] nums1, int[] nums2, int k){
        /* 主要思路:要找到第k (k>1)小的元素，那么就取pivot1 = nums1[k/2-1]和pivot2=nums2[k/2-1]进行比较
         * 这里的"/"表示整除
         * nums1中小于等于pivot1的元素有nums1[0..k/2-2]共计k/2-1个
         * nums2中小于等于pivot2的元素有nums2[0..k/2-2]共计k/2-1个
         * 取pivot=min(pivot1,pivot2),两个数组中小于等于pivot的元素共计不会超过(k/2-1)+(k/2-1)<=k-2个
         * 这样pivot本身最大也只能是第k-1小的元素
         * 如果pivot=pivot1,那么nums1[0..k/2-1]都不可能是第k小的元素。把这些元素全部"删除",剩下的作为新的nums1数组
         * 如果pivot=pivot2,那么nums2[0..k/2-1]都不可能是第k小的元素。把这些元素全部"删除",剩下的作为新的nums2数组
         * 由于我们"删除"了一些元素(这些元素都比第k小的元素小),因此需要修改k的值,减去删除的数的个数.
         */

        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;
        int kthElement = 0;

        while (true) {
            // 边界情况
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2){
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }

            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2){
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            }else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }
}
